package com.ken.ability.gateway.auth;

import com.ken.ability.gateway.auth.manager.RedisAuthenticationManager;
import com.ken.ability.gateway.auth.properties.AuthIgnoreProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
import org.springframework.security.web.server.context.NoOpServerSecurityContextRepository;

@Configuration
@EnableWebFluxSecurity
public class GatewaySecurityConfiguration {

    @Autowired
    private RedisAuthenticationManager redisAuthenticationManager;

    /**
     * 注入忽略的url
     */
    @Autowired
    private AuthIgnoreProperties authIgnoreProperties;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {

        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(redisAuthenticationManager);
        authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());
        authenticationWebFilter.setSecurityContextRepository(NoOpServerSecurityContextRepository.getInstance());

        http
                .formLogin().disable()
                .httpBasic().disable()
                //添加认证拦截器
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                .authorizeExchange()
                //相关url忽略，无需进行认证
                .pathMatchers(authIgnoreProperties.getIgnore().toArray(new String[0])).permitAll()
                //其他任何请求都需要通过认证
                .anyExchange().authenticated()
                .and().logout().logoutUrl("/api-auth/logout")
                .and().csrf().disable();

        //全部放行
//        http.authorizeExchange().anyExchange().permitAll();
        return http.build();
    }
}
